package sqlanalysisgui.view.search;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.ViewPart;

import sqlanalysisgui.session.SessionInfo;
import sqlanalysisgui.view.handler.SearchTableViewDbClickHandler;
import sqlanalysisgui.view.model.TableInfo;
import sqlanalysisgui.view.model.provider.TableInfoContentProvider;
import sqlanalysisgui.view.model.provider.TableInfoLabelProvider;
import sqlanalysisgui.view.model.sorter.SearchTableViewSorter;

import com.cho.core.ExcelCore;
import com.cho.core.db.dao.TableDao;
import com.cho.core.util.StringUtils;
import com.cho.core.vo.TableVo;

import org.eclipse.swt.widgets.Text;

public class SearchTableView extends ViewPart {
	private Logger logger =  Logger.getLogger(this.getClass());
	public static final String ID = "sqlanalysisgui.view.search.SearchTableView"; //$NON-NLS-1$
	private Table table;
	private TableViewer tableViewer;
	private Combo combo;
	private Button btnC;
	private Button btnR;
	private Button btnU;
	private Button btnD;
	
	private TableColumn tblclmnNewColumn;
	private TableColumn tblclmnNewColumn_1;
	private TableColumn tblclmnNewColumn_2;
	private TableColumn tblclmnNewColumn_3;
	private TableColumn tblclmnNewColumn_4;
	private Label label;
	private Combo combo_keyword_condition;
	private Text text_keyword;
	
	public SearchTableView() {
	}

	/**
	 * Create contents of the view part.
	 * @param parent
	 */
	@Override
	public void createPartControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new GridLayout(1, false));
		
		Group group = new Group(container, SWT.NONE);
		group.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Label lblDf = new Label(group, SWT.NONE);
		lblDf.setText("테이블명");
		lblDf.setToolTipText("테이블명으로 검색");
		lblDf.setBounds(10, 20, 56, 15);
		
		combo = new Combo(group, SWT.NONE);
		combo.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.keyCode == 13 || e.keyCode == 16777296){
					searchAction();
				}
			}
		});
		combo.setToolTipText("검색 할 테이블명을 입력하세요.");
		combo.setBounds(72, 17, 296, 23);
		
		label = new Label(group, SWT.NONE);
		label.setToolTipText("테이블명으로 검색");
		label.setText("키워드");
		label.setBounds(10, 52, 56, 15);
		
		combo_keyword_condition = new Combo(group, SWT.NONE);
		combo_keyword_condition.setToolTipText("검색 할 테이블명을 입력하세요.");
		combo_keyword_condition.setItems(new String[] {"AND", "OR"});
		combo_keyword_condition.setBounds(72, 52, 56, 23);
		combo_keyword_condition.select(0);
		
		text_keyword = new Text(group, SWT.BORDER);
		text_keyword.setBounds(138, 52, 230, 21);
		
		text_keyword.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				logger.debug("e.keyCode:" + e.keyCode);
				if(e.keyCode == 13 || e.keyCode == 16777296){
					searchAction();
				}
			}
		});
		
		Label lblCurd = new Label(group, SWT.NONE);
		lblCurd.setToolTipText("테이블명으로 검색");
		lblCurd.setText("CURD");
		lblCurd.setBounds(10, 83, 56, 15);
		
		btnC = new Button(group, SWT.CHECK);
		btnC.setBounds(72, 83, 28, 16);
		btnC.setText("C");
		
		btnR = new Button(group, SWT.CHECK);
		btnR.setText("R");
		btnR.setBounds(107, 83, 28, 16);
		
		btnU = new Button(group, SWT.CHECK);
		btnU.setText("U");
		btnU.setBounds(142, 83, 30, 16);
		
		btnD = new Button(group, SWT.CHECK);
		btnD.setText("D");
		btnD.setBounds(176, 83, 30, 16);
		
		Button btnNewButton = new Button(group, SWT.NONE);
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				logger.debug("검색 버튼 클릭");
				searchAction();
			}
		});
		btnNewButton.setBounds(292, 83, 76, 25);
		btnNewButton.setText("검색");
		
		Button btnNewButton_1 = new Button(group, SWT.NONE);
		btnNewButton_1.setBounds(210, 83, 76, 25);
		btnNewButton_1.setText("엑셀 출력");
		
		final Shell shell = parent.getShell();
		
		btnNewButton_1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				logger.debug("엑셀 출력 버튼 클릭");
				String dir = directoryDialogOpen(shell);
				
				if(StringUtils.isNotEmpty(dir)){
					ExcelCore excelCore = new ExcelCore(dir);
					try {
						excelCore.makeExcel(new TableVo(SessionInfo.getProjectInfo().getProjectName(), combo.getText(), getCrudTypes()));
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					MessageDialog.openInformation(shell, "Info", "엑셀이 생성되었습니다.\n경로: " + dir);
				}else{
					MessageDialog.openInformation(shell, "Info", "엑셀을 저장할 폴더를 선택하세요.");
				}
			}
		});
		
		tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION);
		table = tableViewer.getTable();
		table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
		table.setHeaderVisible(true);
		table.setLinesVisible(true);
		
		TableViewerColumn tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnNewColumn = tableViewerColumn.getColumn();
		tblclmnNewColumn.setWidth(123);
		tblclmnNewColumn.setAlignment(SWT.LEFT);
		tblclmnNewColumn.setText("TABLE");
		tblclmnNewColumn.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				((SearchTableViewSorter) tableViewer.getSorter()).doSort(SearchTableViewSorter.COLUMN_TABLE);
				tableViewer.refresh();
			}
		});
		
		TableViewerColumn tableViewerColumn_1 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnNewColumn_1 = tableViewerColumn_1.getColumn();
		tblclmnNewColumn_1.setWidth(64);
		tblclmnNewColumn_1.setAlignment(SWT.CENTER);
		tblclmnNewColumn_1.setText("CRUD");
		tblclmnNewColumn_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				((SearchTableViewSorter) tableViewer.getSorter()).doSort(SearchTableViewSorter.COLUMN_CRUD);
				tableViewer.refresh();
			}
		});
		
		TableViewerColumn tableViewerColumn_2 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnNewColumn_2 = tableViewerColumn_2.getColumn();
		tblclmnNewColumn_2.setWidth(88);
		tblclmnNewColumn_2.setAlignment(SWT.LEFT);
		tblclmnNewColumn_2.setText("소스 LINE");
		tblclmnNewColumn_2.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				((SearchTableViewSorter) tableViewer.getSorter()).doSort(SearchTableViewSorter.COLUMN_SOURCE_LINE);
				tableViewer.refresh();
			}
		});
		
		TableViewerColumn tableViewerColumn_3 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnNewColumn_3 = tableViewerColumn_3.getColumn();
		tblclmnNewColumn_3.setWidth(88);
		tblclmnNewColumn_3.setAlignment(SWT.LEFT);
		tblclmnNewColumn_3.setText("파일");
		tblclmnNewColumn_3.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				((SearchTableViewSorter) tableViewer.getSorter()).doSort(SearchTableViewSorter.COLUMN_FILE_NAME);
				tableViewer.refresh();
			}
		});
		
		TableViewerColumn tableViewerColumn_4 = new TableViewerColumn(tableViewer, SWT.NONE);
		tblclmnNewColumn_4 = tableViewerColumn_4.getColumn();
		tblclmnNewColumn_4.setWidth(98);
		tblclmnNewColumn_4.setAlignment(SWT.LEFT);
		tblclmnNewColumn_4.setText("소스경로");
		tblclmnNewColumn_4.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				((SearchTableViewSorter) tableViewer.getSorter()).doSort(SearchTableViewSorter.COLUMN_FILE_PATH);
				tableViewer.refresh();
			}
		});

		tableDataSetting();
		
		hookCommand();
		
		createActions();
		initializeToolBar();
		initializeMenu();
	}
	
	private String directoryDialogOpen(final Shell shell){
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();  
	
		DirectoryDialog dialog = new DirectoryDialog(shell);
		String dir = dialog.open();
		
		return dir;
	}
	
	private void searchAction(){
		List<TableInfo> tableInfos = TableDao.selectFileAndTableList(new TableVo(SessionInfo.getProjectInfo().getProjectName(), combo.getText(), this.getCrudTypes()));
		List<TableInfo> tableInfosClone = new ArrayList<TableInfo>();;
		LineNumberReader lr = null;
		
		StringBuffer tableNameSb = null;
		String textLine = null;
		boolean isKeywordAllMatch = combo_keyword_condition.getText().equals("AND");
		String[] text_keywords = text_keyword.getText().toLowerCase().split(",");
		
		SessionInfo.setSearchKeywrods(text_keywords);
		
		
		if(StringUtils.isNotEmpty(text_keyword.getText())){
			for (TableInfo tableInfo : tableInfos) {
				int matchCount = 0;
				try{
					lr = new LineNumberReader(new BufferedReader(new FileReader(new File(tableInfo.getSourcePath()))));
					textLine = null;
					while((textLine = lr.readLine()) != null){
						for (String keyword : text_keywords) {
							if(textLine.toLowerCase().indexOf(keyword.trim()) > -1){
								if(isKeywordAllMatch){
									if(++matchCount == text_keywords.length){
										tableInfosClone.add(tableInfo);
										tableNameSb = new StringBuffer();
										TableInfo searchResult = new TableInfo();
										searchResult = (TableInfo) tableInfo.clone();
										tableNameSb.append("└>").append(searchResult.getTableName());
										searchResult.setTableName(tableNameSb.toString());
										searchResult.setSourceLine(String.valueOf(lr.getLineNumber()));
										tableInfosClone.add(searchResult);
										logger.debug("keyword:" + keyword);
									}
									logger.debug("lr.getLineNumber():" + lr.getLineNumber());
								}else{
									tableInfosClone.add(tableInfo);
									tableNameSb = new StringBuffer();
									TableInfo searchResult = new TableInfo();
									searchResult = (TableInfo) tableInfo.clone();
									tableNameSb.append("└>").append(searchResult.getTableName());
									searchResult.setTableName(tableNameSb.toString());
									searchResult.setSourceLine(String.valueOf(lr.getLineNumber()));
									tableInfosClone.add(searchResult);
								}
							}
						}
					}
				}catch (Exception e){}
			}
		}else{
			tableInfosClone = tableInfos;
		}
		tableViewer.setInput(tableInfosClone);
		tableViewer.refresh();
		tableColumnResize();
	}
	
	private List<String> getCrudTypes(){
		List<String> crudTypes = new ArrayList<String>();
		
		if(btnC.getSelection()){
			crudTypes.add("C");
		}
		
		if(btnR.getSelection()){
			crudTypes.add("R");
		}
		
		if(btnU.getSelection()){
			crudTypes.add("U");
		}
		
		if(btnD.getSelection()){
			crudTypes.add("D");
		}
		
		return crudTypes;
	}
	
	private void hookCommand(){
		hookDoubleClickCommand();
	}
	
	/**
	 * 	더블클릭 이벤트
	 * */
	private void hookDoubleClickCommand() {
		tableViewer.addDoubleClickListener(new IDoubleClickListener() {
			public void doubleClick(DoubleClickEvent event) {
				logger.debug("프로젝트 더블클릭 이벤트 발생");

				IHandlerService handlerService = (IHandlerService) getSite()
						.getService(IHandlerService.class);
				try {
					handlerService.executeCommand(
							SearchTableViewDbClickHandler.ID, null);
					logger.debug("프로젝트 더블클릭 이벤트 발생 핸들러 연결");
				} catch (Exception ex) {
					logger.debug("프로젝트 더블클릭 에러: " + ex);
					throw new RuntimeException(
							SearchTableViewDbClickHandler.ID + " not found");
				}
			}
		});
	}
	
	public void tableDataSetting(){
		/*IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event);
		IWorkbenchPage page = window.getActivePage();
		ProjectListView view = (ProjectListView) page
				.findView(ProjectListView.ID);
		// Get the selection
		ISelection selection = view.getSite().getSelectionProvider()
				.getSelection();
		if (selection != null && selection instanceof IStructuredSelection) {
			Object obj = ((IStructuredSelection) selection).getFirstElement();
			// If we had a selection lets open the editor
			if (obj != null) {
				//layout.addView(ProjectListView.ID, IPageLayout.LEFT, 0.3f, layout.getEditorArea());
				ProjectInfo projectInfo = (ProjectInfo) obj;
				DashboardTableInput input = new DashboardTableInput(projectInfo);
				logger.info("에디터 페이지 열기");
				
				//퍼스펙티브 변경
				IPerspectiveRegistry reg = PlatformUI.getWorkbench().getPerspectiveRegistry();
				window.getActivePage().setPerspective(reg.findPerspectiveWithId(ProjectExplorePerspective.ID));
				
				//열려있는 edtor 모두 닫기
				page.closeAllEditors(true);
				//page.openEditor(input, DashboardMultiPage.ID);// 에디터 페이지 열기
//					page.openEditor(input, DashboardTable.ID);// 에디터 페이지 열기
			}
		}*/
		System.out.println("새로고침");
		combo.setItems(TableDao.selectTableNameList(SessionInfo.getProjectInfo().getProjectName()).toArray(new String[0]));
		tableViewer.setContentProvider(new TableInfoContentProvider());
		tableViewer.setLabelProvider(new TableInfoLabelProvider());
		tableViewer.setInput(TableDao.selectFileAndTableList(new TableVo(SessionInfo.getProjectInfo().getProjectName())));
		getSite().setSelectionProvider(tableViewer);// 이걸 해야 커맨드에서 getSelectionProvider 를 호출할 수 있다.
		tableViewer.setSorter(new SearchTableViewSorter());
		
		tableColumnResize();
	}

	private void tableColumnResize() {
		tblclmnNewColumn.pack();
		tblclmnNewColumn_1.pack();
		tblclmnNewColumn_2.pack();
		tblclmnNewColumn_3.pack();
		tblclmnNewColumn_4.pack();
	}
	
	
	/**
	 * Create the actions.
	 */
	private void createActions() {
		// Create the actions
	}

	/**
	 * Initialize the toolbar.
	 */
	private void initializeToolBar() {
		IToolBarManager toolbarManager = getViewSite().getActionBars()
				.getToolBarManager();
	}

	/**
	 * Initialize the menu.
	 */
	private void initializeMenu() {
		IMenuManager menuManager = getViewSite().getActionBars()
				.getMenuManager();
	}

	@Override
	public void setFocus() {
		// Set the focus
	}
}
